package net.entelijan.cobean.table;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

import net.entelijan.cobean.core.ColumnDesc;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

@SuppressWarnings("unchecked")
public abstract class AbstractBeansTableModel<T> extends AbstractTableModel
		implements ISelectionProvider<T>, ISingleSelectionProvider<T>,
		IBeanProvider<T> {

	private static final long serialVersionUID = 1L;

	@SuppressWarnings("unused")
	private static Log log = LogFactory.getLog(AbstractBeansTableModel.class);

	protected List<BeanWrapper> beans;

	protected List<ColumnDesc> columnDescs;

	protected JTable table;

	public AbstractBeansTableModel(Collection beans,
			List<ColumnDesc> columnDescs, JTable table) {
		ArrayList<BeanWrapper> wbeans = new ArrayList<BeanWrapper>();
		if (beans != null) {
			for (Object bean : beans) {
				wbeans.add(new BeanWrapperImpl(bean));
			}
		}
		this.beans = wbeans;
		this.columnDescs = columnDescs;
		this.table = table;
	}

	@Override
	public T getSingleSelection() {
		T re = null;
		List<T> selection = getSelection();
		if (selection != null && selection.size() > 0) {
			re = selection.get(0);
		}
		return re;
	}

	public int getColumnCount() {
		return columnDescs == null ? 0 : this.columnDescs.size();
	}

	public int getRowCount() {
		return this.beans.size();
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		Object re = null;
		if (columnIndex >= 0) {
			ColumnDesc desc = this.columnDescs.get(columnIndex);
			re = this.beans.get(rowIndex).getPropertyValue(
					desc.getPropertyName());
		}
		return re;
	}

	@Override
	public T getBean(int index) {
		return (T) this.beans.get(index).getWrappedInstance();
	}

}